/*
 * @Author       : Bing Chen chenbing@iocharger.com
 * @Date         : 2025-03-11 09:12:09
 * @LastEditors  : Bing Chen chenbing@iocharger.com
 * @LastEditTime : 2025-03-15 13:00:27
 * @FilePath     : \openchaoji-corelib\shared\src\bs.c
 * @Description  :
 *
 * Copyright (c) 2025 OpenChaoJi
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the icense for the specific language governing permissions and
 * limitations under the License.
 *
 */
#include "bs.h"

/* 初始化比特流结构体 */
void bs_init(bs_t *s, unsigned char *p_data, int i_data) {
    s->p_start = p_data;
    s->p = s->p_start;
    s->p_end = s->p_start + i_data;
    s->i_left = 8; // 初始时指向一个完整字节
}

/* 跳过 n 位（支持跨字节，优化循环）*/
void bs_skip(bs_t *s, int i_count) {
    s->i_left -= i_count;
    while (s->i_left <= 0) {
        s->p++;
        s->i_left += 8;
    }
    // 确保不越界
    if (s->p >= s->p_end) {
        s->p = s->p_end;
        s->i_left = 0;
    }
}

/* 读取 n 位（大端模式）*/
unsigned int bs_read_be(bs_t *s, int i_count) {
    unsigned int result = 0;
    while (i_count > 0) {
        if (s->p >= s->p_end) return 0; // 越界保护
        int bits_to_read = i_count > s->i_left ? s->i_left : i_count;
        result = (result << bits_to_read) | ((*s->p >> (s->i_left - bits_to_read)) & ((1 << bits_to_read) - 1));
        s->i_left -= bits_to_read;
        i_count -= bits_to_read;
        if (s->i_left == 0) {
            s->p++;
            s->i_left = 8;
        }
    }
    return result;
}

/* 读取 n 位（小端模式）*/
unsigned int bs_read_le(bs_t *s, int i_count) {
    unsigned int result = 0;
    for (int i = 0; i < i_count; i++) {
        if (s->p >= s->p_end) return result; // 越界保护
        result |= ((*s->p >> (8 - s->i_left)) & 1) << i;
        s->i_left--;
        if (s->i_left == 0) {
            s->p++;
            s->i_left = 8;
        }
    }
    return result;
}

/* 读取 n 字节（小端模式）*/
void bs_read_bytes_le(bs_t *s, unsigned char *p_data, int n_bytes)
{
    for (int i = 0; i < n_bytes; i++)
    {
        p_data[i] = bs_read_le(s, 8);
    }
}

/* 写入 n 位（大端模式）*/
void bs_write_be(bs_t *s, unsigned int i_bits, int i_count) {
    while (i_count > 0) {
        if (s->p >= s->p_end) return; // 越界保护

        int bits_available = s->i_left;
        int bits_to_write = i_count < bits_available ? i_count : bits_available;

        // 计算掩码清除目标位,避免残留数据影响
        unsigned char mask = ~(((1 << bits_to_write) - 1) << (bits_available - bits_to_write));
        *s->p = (*s->p & mask) | ((i_bits >> (i_count - bits_to_write)) << (bits_available - bits_to_write));

        s->i_left -= bits_to_write;
        i_count -= bits_to_write;

        if (s->i_left == 0) {
            s->p++;
            s->i_left = 8;
        }
    }
}

/* 写入 n 位（小端模式）*/
void bs_write_le(bs_t *s, unsigned int i_bits, int i_count) {
    for (int i = 0; i < i_count; i++) {
        if (s->p >= s->p_end) return;

        int bit_pos = 8 - s->i_left;
        // 计算掩码清除目标位,避免残留数据影响
        unsigned char mask = ~(1 << bit_pos);
        *s->p = (*s->p & mask) | (((i_bits >> i) & 1) << bit_pos);

        s->i_left--;
        if (s->i_left == 0) {
            s->p++;
            s->i_left = 8;
        }
    }
}

/* 写入 n 字节（小端模式）*/
void bs_write_bytes_le(bs_t *s, unsigned char *p_data, int n_bytes)
{
    for (int i = 0; i < n_bytes; i++)
    {
        bs_write_le(s, p_data[i], 8);
    }
}
